<!DOCTYPE html> <!-- -*- html -*- -->
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1">
  <title>Eigenspaces</title>
  <link rel="shortcut icon" href="img/gatech.gif"/>

  
      <link rel="stylesheet" href="css/demo.css?vers=2759ff">
  

  <style>
      

.espace-0 {
    color: var(--palette-green);
}
.espace-1 {
    color: var(--palette-violet);
}
.espace-2 {
    color: var(--palette-brown);
}
.vector {
    color: var(--palette-red)
}
.overlay-popup h3 {
    font-size: 120%;
    text-align: center;
}
.overlay-popup p {
    text-align: center;
}

  </style>

</head>
<body>
    

    
        <script src="js/demo.js?vers=77646a"></script>
    

    <script type="text/javascript">
        "use strict";
        DomReady.ready(function() {

        var color1, color2, color3, colors, i, matrix, matrixT, size, vecColor;

matrix = urlParams.get('mat', 'matrix', [[7 / 2, 0, 3], [-3 / 2, 2, -3], [-3 / 2, 0, -1]]);

size = matrix.length;

switch (size) {
  case 2:
    matrixT = (function() {
      var k, ref, results;
      results = [];
      for (i = k = 0, ref = size; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
        results.push([matrix[0][i], matrix[1][i]]);
      }
      return results;
    })();
    break;
  case 3:
    matrixT = (function() {
      var k, ref, results;
      results = [];
      for (i = k = 0, ref = size; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
        results.push([matrix[0][i], matrix[1][i], matrix[2][i]]);
      }
      return results;
    })();
}

color1 = new Color("green");

color2 = new Color("violet");

color3 = new Color("brown");

colors = [color1, color2, color3];

vecColor = new Color("red");

window.demo = new (size === 2 ? Demo2D : Demo)({
  mathbox: {
    mathbox: {
      warmup: 10,
      splash: false,
      inspect: false
    }
  }
}, function() {
  var clipCube, col, computeOut, diff, eigenspaces, eigenval, eigenvals, eigenvalue, eqnElt, evalStrings, j, k, l, len, len1, len2, matrix2, mult, n, nulBasis, o, onSubspace, popup, ref, ref1, ref2, snap, snapThreshold, snapped, str, subspace, updateCaption, vectorIn, vectorOut, view;
  window.mathbox = this.mathbox;
  view = this.view({
    axes: false,
    grid: size === 2
  });
  clipCube = this.clipCube(view, {
    draw: size === 3,
    hilite: size === 3,
    material: new THREE.MeshBasicMaterial({
      opacity: 0.5,
      transparent: true,
      visible: true,
      depthWrite: false,
      depthTest: true
    })
  });
  view.array({
    channels: 3,
    width: 1,
    live: false,
    data: [0, 0, 0]
  }).point({
    color: "black",
    size: 15,
    zIndex: 3
  });
  eigenvals = eigenvalues(matrix);
  eigenvals.sort(function(x, y) {
    return x[0] - y[0];
  });
  eigenspaces = [];
  for (j = k = 0, len = eigenvals.length; k < len; j = ++k) {
    ref = eigenvals[j], eigenvalue = ref[0], mult = ref[1];
    console.log("Eigenvalue: " + eigenvalue + " (" + mult + ")");
    matrix2 = (function() {
      var l, len1, results;
      results = [];
      for (l = 0, len1 = matrixT.length; l < len1; l++) {
        col = matrixT[l];
        results.push(col.slice());
      }
      return results;
    })();
    for (i = l = 0, ref1 = size; 0 <= ref1 ? l < ref1 : l > ref1; i = 0 <= ref1 ? ++l : --l) {
      matrix2[i][i] -= eigenvalue;
    }
    nulBasis = rowReduce(matrix2, {
      epsilon: 1e-6
    })[0];
    console.log(nulBasis);
    if (mult === 3) {
      clipCube.installMesh();
    }
    subspace = this.subspace({
      vectors: nulBasis,
      name: "eigenspace-" + j,
      live: false,
      color: colors[j],
      lineOpts: {
        zOrder: 0
      },
      surfaceOpts: {
        zOrder: 1
      }
    });
    subspace.draw(clipCube.clipped);
    eigenspaces.push(subspace);
  }
  vectorIn = [1, 2, 3].slice(0, size);
  vectorOut = [0, 0, 0].slice(0, size);
  this.labeledVectors(view, {
    vectors: [vectorIn, vectorOut],
    colors: [vecColor, vecColor.darken(.1).arr(.7)],
    labels: ['x', 'Ax'],
    live: true,
    zeroPoints: true,
    zeroThreshold: 0.3,
    vectorOpts: {
      zIndex: 2
    },
    labelOpts: {
      zIndex: 3
    },
    zeroOpts: {
      zIndex: 3
    }
  });
  switch (size) {
    case 2:
      computeOut = function() {
        var m, v;
        m = matrix;
        v = vectorIn;
        vectorOut[0] = m[0][0] * v[0] + m[0][1] * v[1];
        vectorOut[1] = m[1][0] * v[0] + m[1][1] * v[1];
        return updateCaption();
      };
      break;
    case 3:
      computeOut = function() {
        var m, v;
        m = matrix;
        v = vectorIn;
        vectorOut[0] = m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2];
        vectorOut[1] = m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2];
        vectorOut[2] = m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2];
        return updateCaption();
      };
  }
  snapThreshold = 1.0;
  snapped = new THREE.Vector3();
  diff = new THREE.Vector3();
  onSubspace = -1;
  snap = (function(_this) {
    return function(vec) {
      var len1, n;
      onSubspace = -1;
      if (vec.lengthSq() <= snapThreshold) {
        vec.set(0, 0, 0);
        return;
      }
      for (i = n = 0, len1 = eigenspaces.length; n < len1; i = ++n) {
        subspace = eigenspaces[i];
        subspace.project(vec, snapped);
        diff.copy(vec).sub(snapped);
        if (diff.lengthSq() <= snapThreshold) {
          vec.copy(snapped);
          onSubspace = i;
          return;
        }
      }
    };
  })(this);
  if (vectorIn[0] * vectorIn[0] + vectorIn[1] * vectorIn[1] + vectorIn[2] * vectorIn[2] >= 1e-8) {
    for (i = n = 0, len1 = eigenspaces.length; n < len1; i = ++n) {
      subspace = eigenspaces[i];
      if (subspace.contains(vectorIn)) {
        onSubspace = i;
        break;
      }
    }
  }
  this.draggable(view, {
    points: [vectorIn],
    onDrag: snap,
    postDrag: computeOut
  });
  str = '<p><span id="eqn-here"></span></p>';
  evalStrings = [];
  for (j = o = 0, len2 = eigenvals.length; o < len2; j = ++o) {
    ref2 = eigenvals[j], eigenvalue = ref2[0], mult = ref2[1];
    eigenval = eigenvalue.toFixed(2);
    if (this.urlParams.nospace != null) {
      str += '';
    } else if (this.urlParams.nomult != null) {
      str += ("<p>This is the <span class=\"espace-" + j + "\">") + (eigenval + "-eigenspace</span></p>");
    } else {
      str += ("<p>The <span class=\"espace-" + j + "\">") + (eigenval + "-eigenspace</span> ") + ("has algebraic multiplicity " + mult + " ") + ("and geometric multiplicity " + eigenspaces[j].dim) + "</p>";
    }
    evalStrings.push(katex.renderToString(("A\\color{" + (vecColor.str()) + "}{x} = \\color{" + (colors[j].str()) + "}{" + eigenval + "}") + ("\\color{" + (vecColor.darken(.1).str()) + "}{x}")));
  }
  this.caption(str);
  eqnElt = document.getElementById('eqn-here');
  popup = this.popup();
  updateCaption = (function(_this) {
    return function() {
      str = _this.texMatrix(matrixT);
      str += _this.texVector(vectorIn, {
        color: vecColor.str()
      });
      str += '=';
      str += _this.texVector(vectorOut, {
        color: vecColor.darken(.1).str()
      });
      if (onSubspace !== -1) {
        eigenval = eigenvals[onSubspace][0].toFixed(2);
        str += "= \\color{" + (colors[onSubspace].str()) + "}{" + eigenval + "}";
        str += _this.texVector(vectorIn, {
          color: vecColor.str()
        });
        popup.show("<h3><span class=\"vector\">x</span> is an eigenvector" + (" with eigenvalue <span class=\"espace-" + onSubspace + "\">") + (eigenval + "</span></h3>") + ("<p>" + evalStrings[onSubspace] + "</p>"));
      } else {
        popup.hide();
      }
      return katex.render(str, eqnElt);
    };
  })(this);
  return computeOut();
});


        });
    </script>
</body>
</html>

